<template>
  <page-view :title="false">
    <a-card :bordered="false">
      <a-form :form="form">
        <a-form-item
          label="商品分类"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <a-cascader
            :options="categoryTreeData"
            @change="onCategoryChange"
            placeholder="请选择"
            v-decorator="[
              'categoryValue',
              {rules: [{ required: true, message: '请选择类别' }]}
            ]"
          />
        </a-form-item>

        <a-form-item
          label="标题"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <a-textarea
            v-decorator="[
              'title',
              {initialValue:spu.title,rules: [{ required: true, message: '请输入标题' }]}
            ]"
            placeholder="请输入标题"
          />
        </a-form-item>

        <a-form-item
          label="品牌"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <a-select
            :options="brandOptions"
            v-decorator="[
              'brandId',
              {initialValue:spu.brandId,rules: [{ required: false, message: '请选择品牌' }]}
            ]"
            style="width: 120px"
          />
        </a-form-item>

        <a-form-item
          label="展示图"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <a-upload
            :action="uploadUrl"
            listType="picture"
            :defaultFileList="spu.spuShowImgs"
            class="upload-list-inline"
            @change="spuShowImgsChange"
          >
            <a-button>
              <a-icon type="upload" />upload
            </a-button>
          </a-upload>
        </a-form-item>

        <a-form-item
          label="销售属性"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="{ lg: { span: 20 }, sm: { span: 30 } }"
        >
          <a-card>
            <a-row v-if="spu.saleAttr.length > 0">
              <a-col :span="4" :key="index" v-for="(item,index) in spu.saleAttr[0].options">
                {{ item.name }}:
                <a-upload
                  name="file"
                  listType="picture-card"
                  class="avatar-uploader"
                  :showUploadList="false"
                  :action="uploadUrl"
                  :data="{id: index}"
                  @change="skuImageHandleChange"
                >
                  <img width="100" height="100" v-if="item.imgUrl" :src="item.imgUrl" alt="avatar" />
                  <div v-else>
                    <a-icon type="plus" />
                    <div class="ant-upload-text">Upload</div>
                  </div>
                </a-upload>
              </a-col>
            </a-row>
            <a-row v-for="(item,index) in spu.saleAttr" :key="index" style=" padding: 5px 0;">
              <a-col :span="4">{{ item.name }}:</a-col>
              <a-col :span="18">
                <a-tag
                  v-for="(oItem) in item.options"
                  :key="oItem.name"
                  closable
                  @close="closeOptionTag(oItem.name,index)"
                >{{ oItem.name }}</a-tag>

                <a-input
                  v-if="item.inputVisible"
                  :ref="item.inputRef"
                  type="text"
                  size="small"
                  :style="{ width: '78px' }"
                  @blur="saleAttrOptionsInputConfirm($event,index)"
                  @keyup.enter="saleAttrOptionsInputConfirm($event,index)"
                />
                <a-tag
                  v-else
                  @click="showInput(item.name)"
                  style="background: #fff; borderStyle: dashed;"
                >
                  <a-icon type="plus" />添加
                </a-tag>
              </a-col>
            </a-row>

            <a-row :gutter="5">
              <a-col :span="2">属性:</a-col>
              <a-col :span="16">
                <a-select
                  mode="tags"
                  :options="saleAttrOptions"
                  style="width: 100%"
                  @change="selectSaleAttrChange"
                  placeholder="销售属性"
                />
              </a-col>
            </a-row>
          </a-card>
        </a-form-item>

        <a-form-item
          label="商品sku"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="{ lg: { span: 20 }, sm: { span: 30 } }"
        >
          <a-table
            :columns="skuColumns"
            :dataSource="spu.skuDatas"
            :rowKey="record => record.attrKey"
            bordered
            :pagination="false"
          >
            <template
              v-for="col in ['price','stock' ,'skuCode']"
              :slot="col"
              slot-scope="text, record, index"
            >
              <div :key="col">
                <a-input v-model="spu.skuDatas[index][col]" style="margin: -5px 0" />
              </div>
            </template>

            <template slot="enable" slot-scope="text, record, index">
              <a-radio-group name="radioGroup" v-model="spu.skuDatas[index]['enable']">
                <a-radio :value="true">是</a-radio>
                <a-radio :value="false">否</a-radio>
              </a-radio-group>
            </template>
          </a-table>
        </a-form-item>

        <a-form-item
          label="普通属性"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <a-col :span="10" :key="index" style="margin: 5px 10px" v-for="(item,index) in spu.attr">
            {{ item.name }} :
            <a-select mode="tags" v-model="item.options" placeholder="属性值" />
          </a-col>
        </a-form-item>

        <a-form-item
          label="商品介绍"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <quill-editor v-model="spu.description" :upload-url="uploadUrl" fileName="file" />
        </a-form-item>

        <a-form-item
          label="包装清单"
          :labelCol="formItemLayout.labelCol"
          :wrapperCol="formItemLayout.wrapperCol"
        >
          <a-textarea
            v-decorator="[
              'packingList',
              {initialValue:spu.packingList}
            ]"
            placeholder="请输入包装清单"
          />
        </a-form-item>

        <a-form-item :wrapper-col="{ span: 12, offset: 15 }">
          <a-button type="primary" @click="handleSubmit">保存</a-button>
        </a-form-item>
      </a-form>
    </a-card>
  </page-view>
</template>
<script>
import { PageView, RouteView } from '@/layouts'
import { categoryList, attributeList, brandByCategoryId, spuSave } from '@/api/product'
import QuillEditor from '@/components/Editor/QuillEditor'
export default {
  name: 'SpuAdd',
  components: {
    PageView,
    RouteView,
    QuillEditor
  },
  data () {
    return {
      formItemLayout,
      form: this.$form.createForm(this),
      categoryTreeData: [],
      uploadUrl: process.env.API_BASE_URL + '/base/upload/image',
      spu: {
        description: '',
        spuShowImgs: [],
        skuDatas: [],
        attr: [],
        brandId: '',
        saleAttr: []
      },
      brandOptions: [],
      saleAttrOptions: []
    }
  },
  methods: {
    handleSubmit (e) {
      e.preventDefault()
      this.form.validateFields((err, values) => {
        if (!err) {
          let spuPrice = 0
          const skus = this.spu.skuDatas.map(({ attrKey, price, stock, enable, image, skuCode, ...rest }) => {
            if (spuPrice < price) {
              spuPrice = price
            }
            return {
              attrKey,
              price,
              stock,
              enable,
              image,
              skuCode,
              attrMap: rest
            }
          })
          console.log('skus', skus)

          const saleAttr = this.spu.saleAttr.map((item, index) => {
            const options = []
            item.options.forEach((item, index) => {
              item.id = index + 1
              options.push(item)
            })
            return {
              id: index + 1,
              name: item.name,
              options: options
            }
          })

          const showImgList = this.spu.spuShowImgs.map(item => {
            return item.url
          })

          const params = {
            title: values.title,
            cid1: values.categoryValue[0],
            cid2: values.categoryValue[1],
            cid3: values.categoryValue[2],
            brandId: values.brandId,
            price: spuPrice,
            skus: skus,
            description: this.spu.description,
            showImgList: showImgList,
            attr: this.spu.attr,
            saleAttr: saleAttr,
            packingList: values.packingList
          }
          console.log('save spu params', params)

          spuSave(params).then(res => {
            if (res.status === 0) {
              this.$message.success('保存成功')
              this.$router.push({ path: '/product/spuList' })
            } else {
              this.$message.success(res.msg)
            }
          })
        }
      })
    },
    loadCategoryTreeData () {
      categoryList().then(res => {
        const treeData = []
        res.data.forEach(item => {
          const node = {
            label: item.name,
            value: item.id,
            id: item.id,
            parentId: item.parentId
          }
          if (item.parentId === 0) {
            treeData.push(node)
          }
        })
        treeData.forEach(item => {
          setChildren(item, res.data)
        })
        this.categoryTreeData = treeData
        console.log(this.categoryTreeData)
      })
    },
    onCategoryChange (value) {
      console.log('{}', value)
      if (value.length === 3) {
        attributeList({ categoryId: value[2] }).then(res => {
          const attr = []
          res.data
            .filter(item => !item.sale)
            .forEach(item => {
              attr.push({
                name: item.name
              })
            })
          this.spu.attr = attr
          const saleAttrOptions = []
          res.data
            .filter(item => item.sale)
            .forEach(item => {
              saleAttrOptions.push({
                value: item.name,
                label: item.name
              })
            })
          this.saleAttrOptions = saleAttrOptions
        })

        brandByCategoryId({ categoryId: value[2] }).then(res => {
          const options = []
          res.data.forEach(item => {
            options.push({
              key: item.id,
              label: item.name
            })
          })
          this.brandOptions = options
        })
      }
    },

    closeOptionTag (removedTag, index) {
      console.log('removedTag', removedTag)
      const saleAttr = [...this.spu.saleAttr]
      console.log('closeOptionTag s', saleAttr)
      const options = saleAttr[index].options.filter(tag => tag.name !== removedTag)
      saleAttr[index].options = options
      console.log('closeOptionTag', saleAttr)
      Object.assign(this.spu, {
        saleAttr
      })
      this.spu.skuDatas = this.getSkuDatas()
    },
    selectSaleAttrChange (values) {
      console.log(`selected ${values}`)
      const oldSaleAttr = [...this.spu.saleAttr]
      const saleAttrMap = new Map()
      oldSaleAttr.forEach(oldItem => {
        saleAttrMap.set(oldItem.name, oldItem.options)
      })
      const saleAttr = []
      values.forEach((value, index) => {
        const item = {
          inputRef: 'saleAttrOptionInput' + index,
          inputVisible: false,
          name: value,
          options: []
        }
        const options = saleAttrMap.get(item.name)
        if (options) {
          item.options = options
        }
        saleAttr.push(item)
      })
      Object.assign(this.spu, {
        saleAttr
      })
      console.log('saleAttr', this.spu.saleAttr)
    },
    spuShowImgsChange (info) {
      if (info.file.status === 'done') {
        console.log('fileList', info)
        const fileList = []
        info.fileList.forEach(item => {
          fileList.push({
            uid: item.uid,
            name: item.name,
            status: 'done',
            url: item.response.data.url,
            thumbUrl: item.response.data.url
          })
          item.thumbUrl = item.response.data.url
        })
        this.spu.spuShowImgs = fileList
      }
    },
    skuImageHandleChange (info) {
      if (info.file.status === 'done') {
        const options = [...this.spu.saleAttr[0].options]
        const id = info.file.response.data.id
        const option = options[id]
        option.imgUrl = info.file.response.data.url
        this.spu.saleAttr[0].options = options
      }
    },
    showInput (name) {
      this.spu.saleAttr.forEach(item => {
        if (name === item.name) {
          item.inputVisible = true
          this.$nextTick(function () {
            this.$refs[item.inputRef][0].focus()
          })
        }
      })
    },

    saleAttrOptionsInputConfirm (e, index) {
      const name = e.target.value
      console.log(name, index)
      const saleAttr = [...this.spu.saleAttr]
      const fOptions = saleAttr[index].options.filter(o => o.name === name)
      if (name && fOptions.length === 0) {
        saleAttr[index].options = [...saleAttr[index].options, { name: name }]
      }
      saleAttr[index].inputVisible = false
      Object.assign(this.spu, {
        saleAttr
      })
      console.log('saleAttr', this.spu.saleAttr)

      this.spu.skuDatas = this.getSkuDatas()
    },
    getSkuDatas () {
      const arr = this.spu.saleAttr.filter(s => s.options.length > 0)
      console.log('computed skus', arr)
      if (arr.length === 0) {
        return []
      }
      return arr.reduce(
        (last, attr, index) => {
          const result = []
          last.forEach(o => {
            for (let i = 0; i < attr.options.length; i++) {
              const option = attr.options[i]
              const obj = {}
              Object.assign(obj, o)
              obj[attr.name] = option.name
              // 拼接当前这个特有属性的索引
              const id = i + 1
              obj.attrKey = (o.attrKey || '') + '_' + id
              if (index === arr.length - 1) {
                // 如果发现是最后一组，则添加价格、库存等字段
                Object.assign(obj, { price: 0, stock: 0, image: '', skuCode: '', enable: true })
                // 去掉索引字符串开头的下划线
                obj.attrKey = obj.attrKey.substring(1)
                console.log('computed', obj)
              }
              result.push(obj)
            }
          })
          console.log(result)
          return result
        },
        [{}]
      )
    }
  },
  mounted () {},
  created () {
    this.loadCategoryTreeData()
  },
  computed: {
    skuColumns () {
      const temColumns = []
      this.spu.saleAttr.forEach((item, index) => {
        temColumns.push({
          title: item.name,
          dataIndex: item.name
        })
      })
      if (temColumns.length === 0) {
        return commomSkuColumns
      }
      commomSkuColumns.forEach(item => {
        temColumns.push(item)
      })
      return temColumns
    }
  }
}

function setChildren (pNode, list) {
  const children = getChildren(pNode, list)
  if (children.length !== 0) {
    pNode.children = children
    children.forEach(item => {
      setChildren(item, list)
    })
  }
}

function getChildren (pNode, list) {
  const children = []
  list.forEach(item => {
    if (pNode.id === item.parentId) {
      const cNode = {
        label: item.name,
        value: item.id,
        id: item.id,
        parentId: item.parentId
      }
      children.push(cNode)
    }
  })
  return children
}

const commomSkuColumns = [
  {
    title: '价格',
    dataIndex: 'price',
    width: '20%',
    scopedSlots: { customRender: 'price' }
  },
  {
    title: '库存',
    dataIndex: 'stock',
    width: '20%',
    scopedSlots: { customRender: 'stock' }
  },
  {
    title: '商品编码(可不填)',
    dataIndex: 'skuCode',
    width: '20%',
    scopedSlots: { customRender: 'skuCode' }
  },

  {
    title: '是否上架',
    dataIndex: 'enable',
    width: '15%',
    scopedSlots: { customRender: 'enable' }
  }
]

const formItemLayout = {
  labelCol: { lg: { span: 3 }, sm: { span: 3 } },
  wrapperCol: { lg: { span: 15 }, sm: { span: 30 } }
}
</script>
<style scoped>
/* tile uploaded pictures */
.upload-list-inline >>> .ant-upload-list-item {
  float: left;
  width: 200px;
  margin-right: 8px;
}
.upload-list-inline >>> .ant-upload-animate-enter {
  animation-name: uploadAnimateInlineIn;
}
.upload-list-inline >>> .ant-upload-animate-leave {
  animation-name: uploadAnimateInlineOut;
}
</style>
